/// Pagination utilities and models.
/// 分页工具和模型
///
/// Provides pagination model and utility functions for handling paginated data,
/// including page calculations, rainbow pagination, and list slicing.
/// 提供分页模型和工具函数，用于处理分页数据，包括页面计算、彩虹分页和列表切片。
///
/// Author: sunlunchang
library;

/// Pagination data model.
/// 分页数据模型
///
/// Holds pagination information and data for a single page.
/// 保存单个页面的分页信息和数据。
///
/// Type parameter [T] is the type of items in the page.
/// 类型参数 [T] 是页面中项目的类型。
///
/// Example / 示例:
/// ```dart
/// final page = PageModel<User>(
///   current: 1,
///   size: 20,
///   total: 100,
///   pages: 5,
///   records: userList,
/// );
/// ```
class PageModel<T> {
  /// Current page number / 当前页码
  int current;

  /// Total number of pages / 总页数
  int pages;

  /// Whether this is the last page (optional) / 是否为最后一页（可选）
  bool? isLastPage;

  /// List of records in current page / 当前页的记录列表
  List<T>? records;

  /// Whether to perform total count query / 是否执行总数查询
  bool searchCount;

  /// Number of items per page / 每页项目数
  int size;

  /// Total number of records / 总记录数
  int total;

  /// Creates a pagination model.
  /// 创建分页模型
  ///
  /// All parameters are optional with sensible defaults.
  /// 所有参数都是可选的，具有合理的默认值。
  PageModel({
    this.current = 0,
    this.pages = 0,
    this.isLastPage,
    this.records,
    this.searchCount = false,
    this.size = 0,
    this.total = 0,
  });

  /// Safely checks if this is the last page.
  /// 安全检查是否为最后一页
  ///
  /// Returns [isLastPage] if set, otherwise compares [current] with [pages].
  /// 如果设置了 [isLastPage] 则返回该值，否则比较 [current] 和 [pages]。
  bool isLastPageSafe() => isLastPage ?? current >= pages;

  /// Gets the records list, creating an empty one if null.
  /// 获取记录列表，如果为 null 则创建一个空列表
  ///
  /// Returns a growable list that's safe to modify.
  /// 返回一个可增长的、可安全修改的列表。
  List<T> getListNoNull() => records ??= List.empty(growable: true);
}

/// Pagination utility functions.
/// 分页工具函数类
class PageUtils {
  /// Converts page number and page size to start index.
  /// 将页码和页面大小转换为起始索引
  ///
  /// [pageNo] Page number (1-based) / 页码（从1开始）
  /// [pageSize] Number of items per page / 每页项目数
  ///
  /// Returns the starting index (0-based) for the page.
  /// 返回页面的起始索引（从0开始）。
  ///
  /// Example / 示例: getStart(2, 10) => 10 (second page starts at index 10 / 第二页从索引10开始)
  static int getStart(int pageNo, int pageSize) {
    if (pageNo < 1) pageNo = 1;
    if (pageSize < 1) pageSize = 0;
    return (pageNo - 1) * pageSize;
  }

  /// Converts page number and size to start and end indices.
  /// 将页码和大小转换为起始和结束索引
  ///
  /// [pageNo] Page number (1-based) / 页码（从1开始）
  /// [pageSize] Number of items per page / 每页项目数
  ///
  /// Returns a list with [start, end] indices.
  /// 返回包含 [start, end] 索引的列表。
  ///
  /// Example / 示例: transToStartEnd(2, 10) => [10, 20]
  static List<int> transToStartEnd(int pageNo, int pageSize) {
    final start = getStart(pageNo, pageSize);
    if (pageSize < 1) pageSize = 0;
    return [start, start + pageSize];
  }

  /// Calculates total number of pages.
  /// 计算总页数
  ///
  /// [totalCount] Total number of items / 总项目数
  /// [pageSize] Number of items per page / 每页项目数
  ///
  /// Returns the total number of pages needed.
  /// 返回所需的总页数。
  ///
  /// Example / 示例: totalPage(25, 10) => 3
  static int totalPage(int totalCount, int pageSize) {
    if (pageSize == 0) return 0;
    return totalCount % pageSize == 0
        ? totalCount ~/ pageSize
        : (totalCount ~/ pageSize + 1);
  }

  /// Rainbow pagination algorithm for generating page number sequences.
  /// 彩虹分页算法，用于生成页码序列
  ///
  /// [currentPage] Current page number / 当前页码
  /// [pageCount] Total number of pages / 总页数
  /// [displayCount] Number of page numbers to display (default: 10) / 要显示的页码数量（默认：10）
  ///
  /// Returns a list of page numbers to display in the pagination UI.
  /// 返回要在分页UI中显示的页码列表。
  ///
  /// Example / 示例:
  /// ```dart
  /// rainbow(5, 10, displayCount: 5) => [3, 4, 5, 6, 7]
  /// rainbow(1, 10, displayCount: 5) => [1, 2, 3, 4, 5]
  /// ```
  static List<int> rainbow(int currentPage, int pageCount,
      {int displayCount = 10}) {
    final isEven = displayCount % 2 == 0;
    int left = displayCount ~/ 2;
    int right = displayCount ~/ 2;

    if (isEven) right++;
    final length = pageCount < displayCount ? pageCount : displayCount;
    final result = List.filled(length, 0);

    if (pageCount >= displayCount) {
      if (currentPage <= left) {
        for (int i = 0; i < length; i++) {
          result[i] = i + 1;
        }
      } else if (currentPage > pageCount - right) {
        for (int i = 0; i < length; i++) {
          result[i] = pageCount - displayCount + i + 1;
        }
      } else {
        for (int i = 0; i < length; i++) {
          result[i] = currentPage - left + i + (isEven ? 1 : 0);
        }
      }
    } else {
      for (int i = 0; i < length; i++) {
        result[i] = i + 1;
      }
    }
    return result;
  }

  /// Merges, sorts, and paginates multiple collections.
  /// 合并、排序并分页多个集合
  ///
  /// [pageNo] Page number (1-based) / 页码（从1开始）
  /// [pageSize] Number of items per page / 每页项目数
  /// [comparator] Optional comparison function for sorting / 可选的排序比较函数
  /// [colls] List of collections to merge / 要合并的集合列表
  ///
  /// Returns the requested page of merged and sorted items.
  /// 返回请求的合并和排序后的项目页面。
  ///
  /// Example / 示例:
  /// ```dart
  /// final page = sortPageAll(
  ///   1, 10,
  ///   (a, b) => a.name.compareTo(b.name),
  ///   [users1, users2, users3],
  /// );
  /// ```
  static List<T> sortPageAll<T>(
    int pageNo,
    int pageSize,
    int Function(T a, T b)? comparator,
    List<Iterable<T>> colls,
  ) {
    final merged = <T>[];
    for (final coll in colls) {
      merged.addAll(coll);
    }
    if (comparator != null) merged.sort(comparator);
    return page(pageNo, pageSize, merged);
  }

  /// Paginates a list.
  /// 对列表进行分页
  ///
  /// [pageNo] Page number (1-based) / 页码（从1开始）
  /// [pageSize] Number of items per page / 每页项目数
  /// [list] The list to paginate / 要分页的列表
  ///
  /// Returns the requested page of items, or an empty list if out of range.
  /// 返回请求的项目页面，如果超出范围则返回空列表。
  ///
  /// Example / 示例:
  /// ```dart
  /// final items = ['a', 'b', 'c', 'd', 'e', 'f'];
  /// final page1 = page(1, 2, items); // => ['a', 'b']
  /// final page2 = page(2, 2, items); // => ['c', 'd']
  /// ```
  static List<T> page<T>(int pageNo, int pageSize, List<T>? list) {
    if (list == null || list.isEmpty) return [];
    if (list.length <= pageSize) {
      return pageNo <= 1 ? List.unmodifiable(list) : [];
    }

    final range = transToStartEnd(pageNo, pageSize);
    final start = range[0];
    final end = range[1].clamp(0, list.length);
    return start >= end ? [] : list.sublist(start, end);
  }
}
